package com.example.studentmanagement.fragment;

import java.io.IOException;
import java.util.Collection;

import android.graphics.Bitmap;
import android.hardware.Camera.Parameters;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import com.example.studentmanagement.R;
import com.example.studentmanagement.db.DatabaseHandler;
import com.example.studentmanagement.db.Product;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.jwetherell.quick_response_code.DecoderActivityHandler;
import com.jwetherell.quick_response_code.IDecoderActivity;
import com.jwetherell.quick_response_code.ViewfinderView;
import com.jwetherell.quick_response_code.camera.CameraManager;
import com.jwetherell.quick_response_code.result.ResultHandler;
import com.jwetherell.quick_response_code.result.ResultHandlerFactory;

/**
 * for reading result of qr code [AP-03-5-1]
 * @author ltmen
 *
 */
public class QRCodeReaderFragment extends Fragment implements IDecoderActivity, SurfaceHolder.Callback {
	private static final String TAG = null;
	private static int SIZE = 200;
	private static int WDITH = SIZE;
	private static int HEIGHT = SIZE;
	protected boolean mHasSurface = false;
	protected CameraManager mCameraManager;
	protected DecoderActivityHandler mHandler;
	protected Collection<BarcodeFormat> mDecodeFormats;
    protected String mCharacterSet;
    private SurfaceView mSurfaceView;
	private ViewfinderView mViewfinderView;
    private View mView;
    private TextView mProductCode;
    private TextView mProductName;
    private TextView mProductPrice;
    private TextView mProductFrom;
//    private ImageLoadingTask mImageLoadingTask;
    
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mCameraManager = new CameraManager(getActivity());
	}
	
	
	
	/**
	 * support quick create new instance.
	 * @param displayContents 
	 * @return
	 */
	public static QRCodeReaderFragment makeInstance() {
		QRCodeReaderFragment instance = new QRCodeReaderFragment();
		return instance;
	}
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		mView = inflater.inflate(R.layout.setting_qr_code_reader_screen, null);
		mSurfaceView = (SurfaceView) mView.findViewById(R.id.setting_qr_code_reader_surfaceview);
		mViewfinderView = (ViewfinderView) mView.findViewById(R.id.setting_qr_code_reader_viewfinder);
		mProductCode = (TextView) mView.findViewById(R.id.product_id);
		mProductName = (TextView) mView.findViewById(R.id.product_name);
		mProductPrice = (TextView) mView.findViewById(R.id.product_price);
		mProductFrom = (TextView) mView.findViewById(R.id.product_from);
		return mView;
	}
	
	@Override
	public void onViewCreated(View view, Bundle savedInstanceState) {	
		super.onViewCreated(view, savedInstanceState);
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
		if (holder == null) {
			Log.e(TAG, "SurfaceCreated() gave us a null surface!");
		} else {
			if (!mHasSurface) {
	            mHasSurface = true;
	            initCamera(holder);
	        }
		}
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		mHasSurface = false;
	}

	@Override
	public ViewfinderView getViewfinder() {
		return mViewfinderView;
	}

	@Override
	public Handler getHandler() {
		return mHandler;
	}

	@Override
	public CameraManager getCameraManager() {
		return mCameraManager;
	}

	@Override
	public void handleDecode(Result rawResult, Bitmap barcode) {
		ResultHandler resultHandler = ResultHandlerFactory.makeResultHandler(getActivity(), rawResult);
        handleDecodeInternally(rawResult, resultHandler, barcode);
	}

	/**
	 * Get raw text of QR code
	 * @param rawResult
	 * @param resultHandler
	 * @param barcode
	 */
	private void handleDecodeInternally(Result rawResult, ResultHandler resultHandler, Bitmap barcode) {
		Log.e("", "data: " + rawResult.getText());
		if (rawResult != null && rawResult.getText() != "") {			
			String[] mainStr = rawResult.getText().split("-");
			displayInfor(mainStr);
			saveData(mainStr);
			pause();						
		}		
	}
	
	private void displayInfor(String[] data) {
		
		if (data != null && data.length == 4) {
			mProductCode.setText(String.format(getString(R.string.product_id), data[0]));
			mProductName.setText(String.format(getString(R.string.product_name), data[1]));
			mProductPrice.setText(String.format(getString(R.string.product_price), data[2]));
			mProductFrom.setText(String.format(getString(R.string.product_from), data[3]));				
		}
	}
	
	
	private void saveData(String[] data) {
		 	DatabaseHandler db = new DatabaseHandler(getActivity());	        
	        Log.d("Insert: ", "Inserting ..");
	        db.addContact(new Product(data[0],data[1],data[2],data[3]));
	        
		Toast.makeText(getActivity(), "Saving Data", Toast.LENGTH_SHORT).show();
		(new Handler()).postDelayed(new Runnable() {
			
			@Override
			public void run() {
				Toast.makeText(getActivity(), "Finish", Toast.LENGTH_SHORT).show();
				resume();
			}
		}, 5000);
	}
	
	/**
	 * do connect partner
	 * @param partnerId
	 */
//	private void connectParner(String partnerId) {
//		Log.d(TAG, "start connect partner with partner_id=" + partnerId);
//		BaseWebServiceHandler handler = ZUserHandler.createConnectPartnerHandler(partnerId);
//		postWebServiceTask(TASK_CONNECT_PARTNER, handler, true);
//	}
//	
//	@Override
//	protected void onMainViewCreated(Bundle savedInstanceState, View mainView) {
//		super.onMainViewCreated(savedInstanceState, mainView);
//		if (savedInstanceState != null) {
//			if (getMainManager().isRunningTaskUpdateProfile()) {
//				getHelper().showProgressDlg();
//				getMainManager().setupRequestUserCallback(mOnUpdateProfileCallback);
//			}
//		}
//	}
//	
//	@Override
//	protected void onRequestWebServiceFinish(int serviceTaskId,
//			BaseAsyncTask task, BaseWebServiceHandler serviceHandler,
//			Object result) {
//		super.onRequestWebServiceFinish(serviceTaskId, task, serviceHandler, result);
//		if (ZResult.class.isInstance(result)) {
//			ZResult zresult = (ZResult) result;
//			if (zresult.success) {
//				if (serviceTaskId == TASK_CONNECT_PARTNER) {
//					//connect finish, request user profile again.
//					getMainManager().requestUpdateUserProfile(mOnUpdateProfileCallback);
//				}
//			}
//		}
//	}
//	
//	/**
//	 * used check is updating profile
//	 */
//	private OnRequestUserCallback mOnUpdateProfileCallback = new OnRequestUserCallback() {
//		@Override
//		public void onRequestUserFinish(ZUser userInfo) {
//			reportConnectPartnerSuccess();
//		}
//		
//		@Override
//		public void onRequestUserError(String message) {
//			resume();
//		}
//	};
//	
//	/**
//	 * report that connection to partner finish
//	 */
//	private void reportConnectPartnerSuccess() {
//		getHelper().dismissProgressDlg();
//		Dialog dialog = getHelper().showAlertDlg(getString(R.string.app_name), getString(R.string.msg_connect_partner_ok));
//		dialog.setOnDismissListener(new OnDismissListener() {
//			@Override
//			public void onDismiss(DialogInterface dialog) {
//				backToRootFragment(null);
//			}
//		});
//	}
	
	@Override
	public void onResume() {
		super.onResume();
		resume();
	}
	
	/**
	 * Init camera, view finder
	 */
	@SuppressWarnings("deprecation")
	private void resume() {
        if (mViewfinderView != null) {
            mViewfinderView.setCameraManager(mCameraManager);
        }
        mViewfinderView.setVisibility(View.VISIBLE);
        SurfaceHolder surfaceHolder = null;
        if (mSurfaceView != null) {
        	surfaceHolder = mSurfaceView.getHolder();
        }
        if (mHasSurface) {
            initCamera(surfaceHolder);
        } else {
            surfaceHolder.addCallback(this);
            surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }
	}
	
	/**
	 * Close camera and stop handler
	 */
	private void pause() {
		if (mHandler != null) {
            mHandler.quitSynchronously();
            mHandler = null;
        }
        mCameraManager.closeDriver();
        if (!mHasSurface && mSurfaceView != null) {
            SurfaceHolder surfaceHolder = mSurfaceView.getHolder();
            surfaceHolder.removeCallback(this);
        }
	}
	
	@Override
	public void onPause() {
		super.onPause();
		pause();
	}
	
	/**
	 * Init camera
	 * @param surfaceHolder
	 */
	protected void initCamera(SurfaceHolder surfaceHolder) {
        try {
            mCameraManager.openDriver(surfaceHolder);
            if (mCameraManager.getCamera() != null) {
        		Parameters parameters = mCameraManager.getCamera().getParameters();
                parameters.set("orientation", "landscape");
                mCameraManager.getCamera().setDisplayOrientation(90);
                mCameraManager.getCamera().setParameters(parameters);
        	} 
            if (mHandler == null) {
            	mHandler = new DecoderActivityHandler(this, mDecodeFormats, mCharacterSet, mCameraManager);
            }
        } catch (IOException ioe) {
            Log.d(TAG, "" + ioe.toString());
        } catch (RuntimeException e) {
            Log.d(TAG, "Unexpected error initializing camera", e);
        }
    }
	
//	@Override
//	public boolean onClickOnView(View view) {
//		switch (view.getId()) {
//			case R.id.setting_qr_code_reader_library:
//				openGallery();
//				break;
//			default:
//				break;
//		}
//		return super.onClickOnView(view);
//	}	
//	
//	/**
//	 * Get QRcode bitmap from sdcard
//	 */
//	protected void openGallery() {
//		ImageGalleryIntentPicker picker = new ImageGalleryIntentPicker(getMainActivity());
//		getMainActivity().setOnActivityResult(picker);
//		picker.startPick(mPickerListener);
//	}
	
	/**
	 * To browser image file from sdcard
	 */
//	private ImagePickerListener mPickerListener = new ImagePickerListener() {
//		@Override
//		public void onStartPickerError(int errorCode) {
//			getMainActivity().setOnActivityResult(null);
//		}
//		@Override
//		public void onFinishPickImage(Uri imageUri) {
//			getMainActivity().setOnActivityResult(null);
//			Log.d(TAG, "onFinishPickImage imageUri=" + imageUri);
//			if (imageUri == null) {
//				return;
//			}
//			onLoadImage(imageUri);
//		}
//		
//		@Override
//		public void onCancelPickImage() {
//			getMainActivity().setOnActivityResult(null);
//		}
//	};
	
	/**
	 * Load image, decode and get raw text
	 * @param imageUri
	 */
//	protected void onLoadImage(Uri imageUri) {
//		if (mImageLoadingTask != null) {
//			mImageLoadingTask.stop();
//		}
//		ImageResolution expectedRes = new ImageResolution(WDITH, HEIGHT);
//		mImageLoadingTask = new ImageLoadingTask(getMainActivity(), imageUri, expectedRes );
//		mImageLoadingTask.start(new ImageLoadingTaskListener() {
//			@Override
//			public void onPrepareLoadingImage(ImageLoadingTask task, BaseAsyncTask loadingTask) {
//				getHelper().showProgressDlg(new DialogInterface.OnCancelListener() {
//					@Override
//					public void onCancel(DialogInterface dialog) {
//						if (mImageLoadingTask != null) {
//							mImageLoadingTask.stop();
//						}
//					}
//				});
//			}
//			@Override
//			public void onFinishLoadingImage(ImageLoadingTask task, Bitmap decodedBitmap) {
//				getHelper().dismissProgressDlg();
//				String rawText = getQrCodeFromBitmap(decodedBitmap);
//				connectParner(rawText);
//			}
//		});
//	}
	
	/**
	 * Get QR code raw text from QR code bitmap
	 * @param bm
	 * @return
	 */
	private String getQrCodeFromBitmap(Bitmap bm) {
        if (bm == null) {
            return null;
        }
        int width = bm.getWidth(); 
        int height = bm.getHeight();
        int[] pixels = new int[width * height];
        bm.getPixels(pixels, 0, width, 0, 0, width, height);
        RGBLuminanceSource source = new RGBLuminanceSource(width, height, pixels);
        BinaryBitmap bBitmap = new BinaryBitmap(new HybridBinarizer(source));
        MultiFormatReader reader = new MultiFormatReader();
        try {
            Result result = reader.decode(bBitmap);
            Log.d(TAG, "raw = " + result.getText());
            return result.getText();
        } catch (Exception e) {
            return null;
        }
	}
}


